<?php

Raise::load('core.RaiseStaticClass');
Raise::load('core.RaiseHtmlTag');
Raise::load('core.RaiseCollection');
Raise::load('core.RaiseHtml');
Raise::load('core.Url');
Raise::load('core.RaiseVariable');
Raise::load('core.RaiseConvert');

/**
 * RaiseJavascript helper class
 * Creates Javascript related HTML content
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core.DOM
 * @since 1.2
 */
class RaiseJavascript extends RaiseStaticClass {

    /**
     * Create a Javascript HTML block
     * @param string $content The Javascript code to put in the code block
     * @param boolean $async (optional) Whether to specify the async attribute. Defaults to FALSE.
     * @return RaiseHtmlTag The final HTML script
     * @static
     */
    public static function block($content, $async = null){
        $a = new RaiseCollection();
        if($async){
            $a->add('async', 'true');
        }
        return RaiseHtml::script($content, $a);
    }

    /**
     * Include a Javascript file using URL
     * @param string|Url $file URL of the Javascript file to include on client-side
     * @param boolean $async (optional) Whether to specify the async attribute. Defaults to FALSE.
     * @return RaiseHtmlTag The final HTML script
     * @static
     */
    public static function file($file, $async = null){
        $a = new RaiseCollection();
        if($async){
            $a->add('async', 'true');
        }
        return RaiseHtml::scriptFile($file, $a);
    }

    /**
     * Include phpRaise Javascript helper functions
     * @param string $root (optional) The URL of the raise.js file
     * @return RaiseHtmlTag The final HTML script
     */
    public static function helper($root = ''){
        return self::file(Url::combine($root, 'raise.js'), true);
    }

    /**
     * Provide the Javascript code to change the window title
     * @param string $title The new title to change to
     * @return string
     */
    public static function documentTitle($s){
       return 'document.title=\'' . self::stringEscape($s) . '\';';
    }

    /**
     * Provide the Javascript code to break the current page out of frames
     * @return string
     */
    public static function frameBreaker(){
        return 'if(top!= self){top.location.replace(self.location.href);}';
    }

    /**
     * Include the jQuery Javascript Framework Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#jquery
     */
    public static function includeJquery($version = '1.4.2'){
        return self::file('http://ajax.googleapis.com/ajax/libs/jquery/' . $version . '/jquery.min.js');
    }

    /**
     * Create a Javascript code that is encapsulated in the jQuery onload function
     * @param string $content The Javascript code to be in the onload function
     * @return string The final Javascript code
     * @static
     * @link http://api.jquery.com/jQuery/#jQuery3
     */
    public static function jqueryOnload($content){
        return 'jQuery(function(){ ' . $content . ' });';
    }

    /**
     * Create a Javascript code that uses jQuery to load data from the server and place the returned HTML into the matched element.
     * @param string $selector The jQuery selector to select elements
     * @param string|Url $url The URL to load data from
     * @param RaiseCollection $data (optional) The HTTP GET data to send
     * @param string $callback (optional) The function or name of the callback function to be invoked when AJAX is complete.
     * @return string The final Javascript code
     * @static
     * @link http://api.jquery.com/load/
     */
    public static function jqueryLoad($selector, $url, $data = null, $callback = null){
        if(RaiseVariable::getDataType($data, RaiseVariable::TYPEARRAY)){
            $data = new RaiseCollection($data);
        }
        if($data instanceof RaiseCollection && $callback == null){
            return 'jQuery(\'' . $selector . '\').load(\'' . $url . '\', ' . $data->toJSON() . ');';
        }elseif(RaiseVariable::isType($data, RaiseVariable::TYPESTRING) && $callback == null){
            return 'jQuery(\'' . $selector . '\').load(\'' . $url . '\', ' . RaiseConvert::toString($data) . ');';
        }elseif($data instanceof RaiseCollection && $callback){
            return 'jQuery(\'' . $selector . '\').load(\'' . $url . '\', ' . RaiseConvert::toJSONString($data) . ', \'' . $callback . '\');';
        }elseif(RaiseVariable::isType($data, RaiseVariable::TYPESTRING) && $callback){
            return 'jQuery(\'' . $selector . '\').load(\'' . $url . '\', ' . RaiseConvert::toString($data) . ', \''.$callback . '\');';
        }
        return 'jQuery(\'' . $selector . '\').load(\'' . $url . '\');';
    }

    /**
     * Create a Javascript code that binds an array of events and their corresponding handler code to DOM elements selected by the selector. Note that this method uses .bind() not .live()
     * @param string $selector The jQuery selector to select the elements
     * @param RaiseCollection $ea An array of event => eventHandlerCode to bind to the event
     * @return string The final Javascript code
     * @static
     * @link http://api.jquery.com/category/events/
     */
    public static function jqueryEventBind($selector, $ea){
        $obj = 'jQuery(' . $selector . ')';
        $s = $obj . '';
        foreach($ea as $k => $v){
            $s .= '.bind(\'' . $k . '\', function(event){' . v . '})';
        }
        $s .= ';';
        return $s;
    }

    /**
     * Include the jQuery UI Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#jqueryui
     */
    public static function includeJqueryUi($version = '1.8.5'){
        return self::file('http://ajax.googleapis.com/ajax/libs/jqueryui/' . Url::encode($version) . '/jquery-ui.min.js');
    }

    /**
     * Include the Prototype Javascript Framework Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#mootools
     */
    public static function includeMooTools($version = '1.2.4'){
        return self::file('http://ajax.googleapis.com/ajax/libs/mootools/' . Url::encode($version) . '/mootools-yui-compressed.js');
    }

    /**
     * Include the Prototype Javascript Framework Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#prototype
     */
    public static function includePrototype($version = '1.6.1.0'){
        return self::file('http://ajax.googleapis.com/ajax/libs/prototype/' . Url::encode($version) . '/prototype.js');
    }


    /**
     * Include the Yahoo! User Interface Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#yui
     */
    public static function includeYui($version = '2.8.1'){
        return self::file('http://ajax.googleapis.com/ajax/libs/yui/' . Url::encode($version) . '/build/yuiloader/yuiloader-min.js');
    }


    /**
     * Include the Dojo Javascript Framework Library from Google Libraries API
     * @param string|RaiseVersion $version (optional) Version of the library to use
     * @return RaiseHtmlTag The final HTML script
     * @static
     * @link http://code.google.com/apis/libraries/devguide.html#dojo
     */
    public static function includeDojo($version = '1.5'){
        return self::file('http://ajax.googleapis.com/ajax/libs/dojo/' . Url::encode($version) . '/dojo/dojo.xd.js');
    }

    /**
     * Prompts the User when the page is being closed.
     * @param string $reason The reason of the prompt
     * @return string The final Javascript code
     * @static
     * @link http://msdn.microsoft.com/en-us/library/ms536907%28VS.85%29.aspx
     */
    public static function promptBeforeUnload($reason){
        return 'window.onbeforeunload = function(){return \'' . self::stringEscape($reason) . '\';}';
    }

    /**
     * Provides escaping of string to PHP-to-Javascript strings
     * @param string $s The string to escape
     * @return string The resulting string
     * @static
     */
    public static function stringEscape($s){
       return addcslashes($s, "\\\'\"&\n\r<>");
    }

}
